# -*- coding: utf-8 -*-
from __future__ import (absolute_import, print_function, unicode_literals, division)

__metaclass__ = type

import os

from django.conf import settings
from django.db.backends.mysql import base
import sqlalchemy.pool as pool

MYSQLPOOL = None
DEFAULT_BACKEND = 'QueuePool'


def isiterable(value):
    try:
        iter(value)
        return True
    except TypeError:
        return False


class OldDatabaseProxy():
    def __init__(self, old_connect):
        self.old_connect = old_connect

    def connect(self, **kwargs):
        return self.old_connect(**kwargs)


class HashableDict(dict):
    def __hash__(self):
        items = [(n, tuple(v)) for n, v in self.items() if isiterable(v)]
        return hash(tuple(items))


DatabaseWrapper = base.DatabaseWrapper
OldDatabase = OldDatabaseProxy(base.Database.connect)


def get_pool():
    global MYSQLPOOL
    if MYSQLPOOL is None:
        backend_name = getattr(settings, 'MYSQLPOOL_BACKEND', DEFAULT_BACKEND)
        backend = getattr(pool, backend_name)
        kwargs = getattr(settings, 'MYSQLPOOL_ARGUMENTS', {})
        kwargs.setdefault('poolclass', backend)
        kwargs.setdefault('pool_size', 64)
        kwargs.setdefault('recycle', 9)
        MYSQLPOOL = pool.manage(OldDatabase, **kwargs)
        setattr(MYSQLPOOL, '_pid', os.getpid())

    if getattr(MYSQLPOOL, '_pid', None) != os.getpid():
        pool.clear_managers()
    return MYSQLPOOL


def connect(**kwargs):
    conv = kwargs.pop('conv', None)
    ssl = kwargs.pop('ssl', None)
    if conv:
        kwargs['conv'] = HashableDict(conv)

    if ssl:
        kwargs['ssl'] = HashableDict(ssl)

    return get_pool().connect(**kwargs)


base.Database.connect = connect
